import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import Cookies from 'js-cookie';
import { login as loginApi, register as registerApi, verifyEmail } from '../api/auth';
import { getCurrentUser } from '../api/user';
import { LoginRequest, RegisterRequest, User } from '../types';
import { message } from 'antd';

interface AuthContextType {
  user: User | null;
  token: string | null;
  login: (data: LoginRequest) => Promise<boolean>;
  register: (data: RegisterRequest) => Promise<boolean>;
  verifyEmailAndLogin: (code: string) => Promise<boolean>;
  logout: () => void;
  isAuthenticated: boolean;
  loading: boolean;
  isAdmin: () => boolean;
  isModerator: () => boolean;
  refreshUser: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    initAuth();
  }, []);

  const initAuth = async () => {
    // 从cookie中恢复token
    const savedToken = Cookies.get('token');
    if (savedToken) {
      setToken(savedToken);
      // 获取用户信息
      await fetchUserInfo();
    }
    setLoading(false);
  };

  const fetchUserInfo = async (): Promise<boolean> => {
    try {
      const response = await getCurrentUser();
      if (response.code === 200) {
        setUser(response.data);
        return true;
      } else if (response.code === 401 || response.code === 403) {
        // 认证失败，清除登录状态
        console.log('Token已过期或无效，清除登录状态');
        logout();
        return false;
      } else {
        console.error('获取用户信息失败:', response.message);
        return false;
      }
    } catch (error: any) {
      console.error('获取用户信息失败:', error);

      // 只有在确认是认证相关错误时才清除登录状态
      if (error?.response?.status === 401 || error?.response?.status === 403) {
        console.log('Token已过期或无效，清除登录状态');
        logout();
        return false;
      } else {
        // 网络错误或其他错误，不清除登录状态
        console.log('网络错误或其他错误，保持当前登录状态');
        return false;
      }
    }
  };

  const login = async (data: LoginRequest): Promise<boolean> => {
    try {
      const response = await loginApi(data);
      if (response.code === 200) {
        const { token: newToken } = response.data;
        if (newToken) {
          setToken(newToken);
          Cookies.set('token', newToken, { expires: 7 }); // 7天过期
          // 获取用户信息
          await fetchUserInfo();
          message.success('登录成功');
          return true;
        }
      } else {
        message.error(response.message || '登录失败');
        return false;
      }
    } catch (error) {
      console.error('登录失败:', error);
      message.error('登录失败，请检查网络连接');
      return false;
    }
    return false;
  };

  const register = async (data: RegisterRequest): Promise<boolean> => {
    try {
      const response = await registerApi(data);
      if (response.code === 200) {
        // 注册成功但需要验证邮箱，不设置token
        if (response.data.needVerification) {
          message.success(response.data.message || '注册成功，请查收邮箱验证码');
          return true; // 返回true表示注册请求成功
        } else {
          // 如果不需要验证（保持兼容性）
          const { token: newToken } = response.data;
          if (newToken) {
            setToken(newToken);
            Cookies.set('token', newToken, { expires: 7 });
            await fetchUserInfo();
            message.success('注册成功');
            return true;
          }
        }
      } else {
        message.error(response.message || '注册失败');
        return false;
      }
    } catch (error) {
      console.error('注册失败:', error);
      message.error('注册失败，请检查网络连接');
      return false;
    }
    return false;
  };

  const verifyEmailAndLogin = async (code: string): Promise<boolean> => {
    try {
      const response = await verifyEmail(code);
      if (response.code === 200 && response.data) {
        const { token: newToken } = response.data;
        if (newToken) {
          setToken(newToken);
          Cookies.set('token', newToken, { expires: 7 });
          await fetchUserInfo();
          message.success('邮箱验证成功，注册完成！');
          return true;
        }
      } else {
        message.error(response.message || '验证失败');
        return false;
      }
    } catch (error) {
      console.error('验证失败:', error);
      message.error('验证失败，请检查验证码');
      return false;
    }
    return false;
  };

  const logout = () => {
    setUser(null);
    setToken(null);
    Cookies.remove('token');
    message.success('已退出登录');
  };

  const isAdmin = (): boolean => {
    return user !== null && user.userClass >= 4; // 管理员等级是4
  };

  const isModerator = (): boolean => {
    return user !== null && user.userClass >= 3; // VIP及以上（包括管理员）
  };

  const refreshUser = async (): Promise<void> => {
    if (token) {
      await fetchUserInfo();
    }
  };

  const value: AuthContextType = {
    user,
    token,
    login,
    register,
    logout,
    isAuthenticated: !!token,
    loading,
    verifyEmailAndLogin,
    isAdmin,
    isModerator,
    refreshUser,
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}; 